package com.gmail.at.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.gmail.at.form.ScheduleGrid;
import com.gmail.at.model.Passenger;
import com.gmail.at.model.Schedule;
import com.gmail.at.model.Station;
import com.gmail.at.model.Ticket;
import com.gmail.at.model.Train;
import com.gmail.at.service.ScheduleService;
import com.gmail.at.service.StationService;
import com.gmail.at.service.TrainService;
import com.google.common.collect.Lists;

@RequestMapping("/schedules")
@Controller
public class ScheduleController {
	final Logger logger = LoggerFactory.getLogger(ScheduleController.class);

	@Autowired
	private ScheduleService scheduleService;

	@Autowired
	private StationService stationService;

	@Autowired
	private TrainService trainService;

	@Autowired
	MessageSource messageSource;
	
	@RequestMapping(method = RequestMethod.GET)
	public String list(Model uiModel) {
		logger.info("Listing schedules");
		Schedule schedule = new Schedule();
		uiModel.addAttribute("schedule", schedule);
		return "schedules/list";
	}
	
	@RequestMapping(value = "/listgrid", method = RequestMethod.GET, produces = "application/json")
	@ResponseBody
	public ScheduleGrid listGrid(
			@RequestParam(value = "page", required = false) Integer page,
			@RequestParam(value = "rows", required = false) Integer rows,
			@RequestParam(value = "sidx", required = false) String sortBy,
			@RequestParam(value = "sord", required = false) String order) {
		logger.info("Listing schedules for grid with page: {}, rows: {}", page,
				rows);
		logger.info("Listing schedules for grid with sort: {}, order: {}",
				sortBy, order);
		Sort sort = null;
		String orderBy = sortBy;
		if (orderBy != null && orderBy.equals("arrivalString")) {
			orderBy = "dateOfArrival";
		}	
		if (orderBy != null && orderBy.equals("departureString")) {
			orderBy = "dateOfDeparture";
		}	
		if (orderBy != null && order != null) {
			if (order.equals("desc")) {
				sort = new Sort(Sort.Direction.DESC, orderBy);
			} else
				sort = new Sort(Sort.Direction.ASC, orderBy);
		}
		PageRequest pageRequest = null;
		if (sort != null) {
			pageRequest = new PageRequest(page - 1, rows, sort);
		} else {
			pageRequest = new PageRequest(page - 1, rows);
		}
		Page<Schedule> schedulePage = scheduleService.findAllByPage(pageRequest);
		ScheduleGrid scheduleGrid = new ScheduleGrid();
		scheduleGrid.setCurrentPage(schedulePage.getNumber() + 1);
		scheduleGrid.setTotalPages(schedulePage.getTotalPages());
		scheduleGrid.setTotalRecords(schedulePage.getTotalElements());
		scheduleGrid.setScheduleData(Lists.newArrayList(schedulePage.iterator()));
		return scheduleGrid;
	}
	
	
	@RequestMapping(value = "/{scheduleID}", params = "delete", method = RequestMethod.GET)
	public @ResponseBody String delete(@PathVariable("scheduleID") Integer id, Model uiModel) {
		return scheduleService.delete(id);
	}
	
	@RequestMapping(value = "/{scheduleID}", params = "form", method = RequestMethod.POST)
	public @ResponseBody String update(@Valid Schedule schedule, @PathVariable("scheduleID") Integer id, BindingResult bindingResult,
			Model uiModel, HttpServletRequest httpServletRequest,
			RedirectAttributes redirectAttributes, Locale locale) {
		logger.info("Updating schedules");
		if (bindingResult.hasErrors()) {
			return "Invalid schedule information (check fields)";
		}
		Schedule temp = scheduleService.findById(id);
		if (temp != null) {
			String result = scheduleService.update(temp, schedule);
			if (result.equals("ok")) {	
				return "ok";
			} else {
				return result;
			}
		} else {
			return "Schedule with this id wasn't found, update your list";
		}
	}
	

	@RequestMapping(method = RequestMethod.POST)
	public @ResponseBody String create(@Valid Schedule schedule,
			BindingResult bindingResult, Model uiModel,
			HttpServletRequest httpServletRequest,
			RedirectAttributes redirectAttributes, Locale locale) {
		logger.info("Creating schedule");
		if (bindingResult.hasErrors()) {
			return "Invalid schedule information (check fields)";
		}
		String result = scheduleService.save(schedule);
    	if (result.equals("ok")) {
    		return "ok";   
    	} else {
			return result;
    	}
	}
	
	@RequestMapping(method = RequestMethod.GET, params = "autostations")
	public @ResponseBody List<Station> autoStations(Model uiModel) {
		logger.info("Listing stations autocompl");
		List<Station> stations = stationService.findAll();
		return stations;
	}
	
	@RequestMapping(method = RequestMethod.GET, params = "autotrains")
	public @ResponseBody List<Train> autoTrains(Model uiModel) {
		logger.info("Listing trains autocompl");
		List<Train> trains = trainService.findAll();
		return trains;
	}
	
	@RequestMapping(value = "/{scheduleID}", params = "show", method = RequestMethod.GET)
	public String showPassnegers(@PathVariable("scheduleID") Integer id,
			Model uiModel) {
		List<Passenger> passengers = null;
		for (Ticket t : scheduleService.findById(id).getTickets()) {
			if(passengers == null) {
				passengers = new ArrayList<Passenger>();
			}
			passengers.add(t.getPassenger());
		}
		uiModel.addAttribute("passengers", passengers);
		return "schedules/passengers";
	}
}
